#include "string.h"
#include "iot_debug.h"
#include "iot_vat.h"

E_OPENAT_NETWORK_STATE network_state = 0;
static F_OPENAT_NETWORK_IND_CB g_s_OpenatNetIndCb = NULL;

int CsqValue = 0;
static AtCmdRsp AtCmdCb_csq(u8* pRspStr)
{
	iot_debug_print("[vat]AtCmdCb_csq");
    AtCmdRsp  rspValue = AT_RSP_WAIT;
    u8 *rspStrTable[ ] = {"+CME ERROR","+CSQ: "};
    s16  rspType = -1;
	u8 zero = '0';
    u8  i = 0;
    u8  *p = pRspStr + 2;
    for (i = 0; i < sizeof(rspStrTable) / sizeof(rspStrTable[0]); i++)
    {
        if (!strncmp(rspStrTable[i], p, strlen(rspStrTable[i])))
        {
            rspType = i;
            if (rspType == 1){
				if(p[strlen(rspStrTable[rspType])+1] == ',')
				{
			  		CsqValue = STR_TO_INT(p[strlen(rspStrTable[rspType])]);
				}else
				{
					CsqValue = STR_TO_INT(p[strlen(rspStrTable[rspType])])*10 + STR_TO_INT(p[strlen(rspStrTable[rspType])+1]);
				}
            }
            break;
        }
    }
    switch (rspType)
    {
        case 0:  /* ERROR */
        rspValue = AT_RSP_ERROR;
        break;

        case 1:  /* +CSQ */
	    if(CsqValue){
			iot_debug_print("[vat]csq: %d", CsqValue);
        		rspValue  = AT_RSP_STEP+1;
	   	}else
			rspValue  = AT_RSP_STEP-1;
        break;

        default:
        break;
    }
    return rspValue;
}

static AtCmdRsp AtCmdCb_csqval(u8* pRspStr)
{
	iot_debug_print("[vat]AtCmdCb_csqval");
    AtCmdRsp  rspValue = AT_RSP_WAIT;
    u8 *rspStrTable[ ] = {"+CME ERROR","+CSQ: "};
    s16  rspType = -1;
	u8 zero = '0';
    u8  i = 0;
    u8  *p = pRspStr + 2;
    for (i = 0; i < sizeof(rspStrTable) / sizeof(rspStrTable[0]); i++)
    {
        if (!strncmp(rspStrTable[i], p, strlen(rspStrTable[i])))
        {
            rspType = i;
            if (rspType == 1){
				if(p[strlen(rspStrTable[rspType])+1] == ',')
				{
			  		CsqValue = STR_TO_INT(p[strlen(rspStrTable[rspType])]);
				}else
				{
					CsqValue = STR_TO_INT(p[strlen(rspStrTable[rspType])])*10 + STR_TO_INT(p[strlen(rspStrTable[rspType])+1]);
				}
            }
            break;
        }
    }
    switch (rspType)
    {
        case 0:  /* ERROR */
        rspValue = AT_RSP_ERROR;
        break;

        case 1:  /* +CSQ */
			rspValue  = AT_RSP_STEP+1;
        break;

        default:
        break;
    }
    return rspValue;
}


static AtCmdRsp AtCmdCb_cgatt(u8* pRspStr)
{
	iot_debug_print("[vat]AtCmdCb_cgatt");
    AtCmdRsp  rspValue = AT_RSP_WAIT;
    u8 *rspStrTable[] = {"ERROR","+CGATT: 1","+CGATT: 0"};
    s16  rspType = -1;
    u8  i = 0;
    u8  *p = pRspStr + 2;
	
    for (i = 0; i < sizeof(rspStrTable) / sizeof(rspStrTable[0]); i++)
    {
        if (!strncmp(rspStrTable[i], p, strlen(rspStrTable[i])))
        {
            rspType = i;
            break;
        }
    }
	iot_debug_print("[vat] rspType %d",rspType);
    switch (rspType)
    {
        case 0:  /* ERROR */
        rspValue = AT_RSP_ERROR;
        break;

        case 1:  /* attached */
        rspValue  = AT_RSP_STEP+3;
        break;

        case 2:  /* detached */
        rspValue  = AT_RSP_STEP+2;
        break;

        default:
        break;
    }
    return rspValue;
}
int CgactCid = 0;
static AtCmdRsp AtCmdCb_cgact(u8* pRspStr)
{
	iot_debug_print("[vat]AtCmdCb_cgact");
    AtCmdRsp  rspValue = AT_RSP_WAIT;
    u8 *rspStrTable[] = {"ERROR","+CGACT: ","OK"};
    s16  rspType = -1;
	int CgactValue = 0;
    u8  i = 0;
    u8  *p = pRspStr + 2;
	
    for (i = 0; i < sizeof(rspStrTable) / sizeof(rspStrTable[0]); i++)
    {
        if (!strncmp(rspStrTable[i], p, strlen(rspStrTable[i])))
        {
            rspType = i;
		   CgactCid = STR_TO_INT(p[strlen(rspStrTable[rspType])]);
 	  	   CgactValue = STR_TO_INT(p[strlen(rspStrTable[rspType])+2]);
            break;
        }
    }
	iot_debug_print("[vat] rspType %d",rspType);
    switch (rspType)
    {
        case 0:
        rspValue = AT_RSP_ERROR;
        break;

        case 1:
	    if(CgactValue){
			network_state = OPENAT_NETWORK_LINKED;
			networkStatusChange();
        		rspValue  = AT_RSP_FUN_OVER;
		}else{
			network_state = OPENAT_NETWORK_DISCONNECT;
			networkStatusChange();
			rspValue  = AT_RSP_CONTINUE;
		}
        break;

        case 2:
	    network_state = OPENAT_NETWORK_DISCONNECT;
		networkStatusChange();
        rspValue  = AT_RSP_CONTINUE;
        break;

        default:
        break;
    }
    return rspValue;
}


BOOL network_connect(T_OPENAT_NETWORK_CONNECT* connectParam)
{
	BOOL result = FALSE;
	iot_vat_Modeuleinit();
	network_state = OPENAT_NETWORK_LINKING;
	networkStatusChange();
	AtCmdEntity atCmdInit[]={
		{"AT"AT_CMD_END,4,NULL},
		{AT_CMD_DELAY"2000",10,NULL},
		{"AT+CSQ"AT_CMD_END,8,AtCmdCb_csq},
		{AT_CMD_DELAY"2000",10,NULL},
		{"AT+CGACT?"AT_CMD_END,11,AtCmdCb_cgact},
		{AT_CMD_DELAY"1000",10,NULL},
		{"AT+CGDCONT=1,IP,CMNET"AT_CMD_END,22,NULL},
		{AT_CMD_DELAY"20",8,NULL},
		{"AT*AUTHReq=1,1"AT_CMD_END,16,NULL},
		{AT_CMD_DELAY"20",8,NULL},
		{"AT+CGATT=1"AT_CMD_END,12,NULL},
		{"AT+CGACT=1,1"AT_CMD_END,14,NULL},
	};
	u8 pAtApn[50] = {0};
	u8 pAtAuthReq[100] = {0};	
	if(connectParam->apn)
	{
		sprintf(pAtApn,"AT+CGDCONT=1,IP,%s%s",connectParam->apn,AT_CMD_END);
		atCmdInit[6].p_atCmdStr = pAtApn;
		atCmdInit[6].cmdLen = strlen(pAtApn);
		atCmdInit[6].p_atCmdCallBack = NULL;
	}
	if(connectParam->password || connectParam->username)
	{
		sprintf(pAtAuthReq,"AT*AUTHReq=1,1,%s,%s%s",connectParam->username, connectParam->password,AT_CMD_END);
		atCmdInit[8].p_atCmdStr = pAtAuthReq;
		atCmdInit[8].cmdLen = strlen(pAtAuthReq);
		atCmdInit[8].p_atCmdCallBack = NULL;
	}
	result = iot_vat_queue_fun_append(atCmdInit,sizeof(atCmdInit) / sizeof(atCmdInit[0]));
	iot_vat_SendCMD();
    return result;
}

BOOL network_disconnect(BOOL flymode)
{
	iot_vat_Modeuleinit();
	BOOL result = FALSE;
	network_state = OPENAT_NETWORK_GOING_DOWN;
	networkStatusChange();
	AtCmdEntity atCmdInit[]={
		{"AT"AT_CMD_END,4,NULL},
		{AT_CMD_DELAY"2000",10,NULL},
		{"AT+CGACT?"AT_CMD_END,11,AtCmdCb_cgact},
		{AT_CMD_DELAY"1000",10,NULL},
		{"AT+CGACT=0,1"AT_CMD_END,4,NULL},
	};
	u8 pAtCid[20] = {0};
	sprintf(pAtCid,"AT+CGACT=0,%s%s",CgactCid,AT_CMD_END);
	atCmdInit[4].p_atCmdStr = pAtCid;
	atCmdInit[4].cmdLen = strlen(pAtCid);
	atCmdInit[4].p_atCmdCallBack = NULL;
	result = iot_vat_queue_fun_append(atCmdInit,sizeof(atCmdInit) / sizeof(atCmdInit[0]));
	iot_vat_SendCMD();
    return result;
}

BOOL network_get_status(T_OPENAT_NETWORK_STATUS* status)
{
	BOOL result = FALSE;
	iot_vat_Modeuleinit();
	AtCmdEntity atCmdInit[]={
		{"AT"AT_CMD_END,4,NULL},
		{"AT+CSQ"AT_CMD_END,8,AtCmdCb_csqval},
	};
	result = iot_vat_queue_fun_append(atCmdInit,sizeof(atCmdInit) / sizeof(atCmdInit[0]));
	iot_vat_SendCMD();
	extern BOOL simpresent;
	iot_os_sleep(1000);
	status->state = network_state;
	status->simpresent= simpresent;
	status->csq = CsqValue;
     return result;
}

BOOL network_set_cb(F_OPENAT_NETWORK_IND_CB indCb)
{
	iot_vat_Modeuleinit();
	g_s_OpenatNetIndCb = indCb;
	return TRUE;
}

VOID networkStatusChange(VOID)
{
  static E_OPENAT_NETWORK_STATE orgState = OPENAT_NETWORK_DISCONNECT;
  E_OPENAT_NETWORK_STATE newState = network_state;
  if(orgState != newState)
  {
  	if(g_s_OpenatNetIndCb)
	{
	  g_s_OpenatNetIndCb(newState);
	}
	orgState = newState;
  }  
}

